package jenkins

import (
	"bytes"
	"encoding/xml"
	"io/ioutil"
	"log"
	"strings"
	"text/template"
)

type JobParam struct {
	Script string
}

type BackendJobCreateParam struct {
	EnvName string

	DockerLabel string
	Git string
	JobName string

	ServiceName string
	CeleryBeatServiceName string
	CeleryWorkerServiceName string

	BackendStaticVolume string
	BackendMediaVolume string

	DockerNetwork string
	DockerRepository string
	DockerManagerHost string
	DockerManagerUser string
	DockerManagerPort string

	JobScriptTemplateFile string
	JobConfigTemplateFile string
}

type CustomerJobCreateParam struct {
	EnvName string
	// docker service name
	ServiceName string
	JobName string
	// docker label
	DockerLabel string
	MainDomain string
	SubDomain string
	Git string

	Port int
	DocVolume string

	BackendServiceName string
	BackendStaticVolume string
	BackendPubMediaVolume string

	DockerNetwork string
	DockerRepository string
	DockerManagerHost string
	DockerManagerUser string
	DockerManagerPort string
	DockerBuildResourceRoot string

	JobScriptTemplateFile string
	JobConfigTemplateFile string
}

type AdminJobCreateParam struct {
	EnvName string
	// docker service name
	ServiceName string
	JobName string
	// docker label
	DockerLabel string
	MainDomain string
	SubDomain string
	Git string

	Port int
	DocVolume string

	BackendServiceName string

	DockerNetwork string
	DockerRepository string
	DockerManagerHost string
	DockerManagerUser string
	DockerManagerPort string
	DockerBuildResourceRoot string

	JobScriptTemplateFile string
	JobConfigTemplateFile string
}

type MobileJobCreateParam struct {
	EnvName string
	KHost string
	// docker service name
	ServiceName string
	JobName string
	// docker label
	DockerLabel string
	MainDomain string
	SubDomain string
	Git string

	Port int
	DocVolume string

	BackendServiceName string

	DockerNetwork string
	DockerRepository string
	DockerManagerHost string
	DockerManagerUser string
	DockerManagerPort string
	DockerBuildResourceRoot string

	JobScriptTemplateFile string
	JobConfigTemplateFile string
}

type DBJobCreateParam struct {
	EnvName string
	ServiceName string
	JobName string
	DockerLabel string

	DockerManagerHost string
	DockerManagerUser string
	DockerManagerPort string

	BackendServiceName string
	CeleryBeatServiceName string
	CeleryWorkerServiceName string

	Port int

	JobScriptTemplateFile string
	JobConfigTemplateFile string
}

type ApplicationRestartJobCreateParam struct {
	EnvName string
	JobName string

	BackendServiceName string
	CeleryWorkerServiceName string
	CeleryBeatServiceName string

	DockerManagerHost string
	DockerManagerUser string
	DockerManagerPort string

	JobScriptTemplateFile string
	JobConfigTemplateFile string
}

func CreateBackendJob(createParam BackendJobCreateParam)  error {
	// parse script
	scriptTemplate, err := ioutil.ReadFile(createParam.JobScriptTemplateFile)
	if err != nil {
		log.Println(err)
		return err
	}
	tmpl, err := template.New("scriptTemplate").Parse(string(scriptTemplate))
	if err != nil {
		log.Println(err)
		return err
	}
	var scriptContent bytes.Buffer
	err = tmpl.Execute(&scriptContent, createParam)
	if err != nil {
		log.Println(err)
		return err
	}
	// escape " ' < > &
	var escapedScript bytes.Buffer
	err = xml.EscapeText(&escapedScript, scriptContent.Bytes())
	if err != nil {
		log.Println(err)
		return err
	}

	// parse the customer portal job template
	configTemplate, err := ioutil.ReadFile(createParam.JobConfigTemplateFile)
	if err != nil {
		log.Println(err)
		return err
	}
	tmpl, err = template.New("configTemplate").Parse(string(configTemplate))
	if err != nil {
		log.Println(err)
		return err
	}
	jobParam := JobParam{
		Script: escapedScript.String(),
	}
	var jobConfig bytes.Buffer
	err = tmpl.Execute(&jobConfig, jobParam)
	if err != nil {
		log.Println(err)
		return err
	}
	jobCreateParam := JobCreateParam{
		EnvName: strings.ToUpper(createParam.EnvName),
		JobName: createParam.JobName,
		Config:  &jobConfig,
	}
	if err = CreateViewJob(jobCreateParam); err != nil {
		log.Println(err)
		return err
	}
	return nil
}

func CreateCustomerPortalJob(createParam CustomerJobCreateParam)  error {
	// parse script
	scriptTemplate, err := ioutil.ReadFile(createParam.JobScriptTemplateFile)
	if err != nil {
		log.Println(err)
		return err
	}
	tmpl, err := template.New("scriptTemplate").Parse(string(scriptTemplate))
	if err != nil {
		log.Println(err)
		return err
	}
	var scriptContent bytes.Buffer
	err = tmpl.Execute(&scriptContent, createParam)
	if err != nil {
		log.Println(err)
		return err
	}
	// escape " ' < > &
	var escapedScript bytes.Buffer
	err = xml.EscapeText(&escapedScript, scriptContent.Bytes())
	if err != nil {
		log.Println(err)
		return err
	}
	// parse the customer portal job template
	configTemplate, err := ioutil.ReadFile(createParam.JobConfigTemplateFile)
	if err != nil {
		log.Println(err)
		return err
	}
	tmpl, err = template.New("configTemplate").Parse(string(configTemplate))
	if err != nil {
		log.Println(err)
		return err
	}
	jobParam := JobParam{
		Script: escapedScript.String(),
	}
	var jobConfig bytes.Buffer
	err = tmpl.Execute(&jobConfig, jobParam)
	if err != nil {
		log.Println(err)
		return err
	}
	// create customer portal job under view
	jobCreateParam := JobCreateParam{
		EnvName: strings.ToUpper(createParam.EnvName),
		JobName: createParam.JobName,
		Config:  &jobConfig,
	}
	if err = CreateViewJob(jobCreateParam); err != nil {
		log.Println(err)
		return err
	}
	return nil
}

func CreateAdminPortalJob(createParam AdminJobCreateParam)  error {
	// parse script
	scriptTemplate, err := ioutil.ReadFile(createParam.JobScriptTemplateFile)
	if err != nil {
		log.Println(err)
		return err
	}
	tmpl, err := template.New("scriptTemplate").Parse(string(scriptTemplate))
	if err != nil {
		log.Println(err)
		return err
	}
	var scriptContent bytes.Buffer
	err = tmpl.Execute(&scriptContent, createParam)
	if err != nil {
		log.Println(err)
		return err
	}

	// escape " ' < > &
	var escapedScript bytes.Buffer
	err = xml.EscapeText(&escapedScript, scriptContent.Bytes())
	if err != nil {
		log.Println(err)
		return err
	}

	// parse the customer portal job template
	configTemplate, err := ioutil.ReadFile(createParam.JobConfigTemplateFile)
	if err != nil {
		log.Println(err)
		return err
	}
	tmpl, err = template.New("configTemplate").Parse(string(configTemplate))
	if err != nil {
		log.Println(err)
		return err
	}
	jobParam := JobParam{
		Script: escapedScript.String(),
	}

	var jobConfig bytes.Buffer
	err = tmpl.Execute(&jobConfig, jobParam)
	if err != nil {
		log.Println(err)
		return err
	}
	// create admin portal job under view
	jobCreateParam := JobCreateParam{
		EnvName: strings.ToUpper(createParam.EnvName),
		JobName: createParam.JobName,
		Config:  &jobConfig,
	}
	if err = CreateViewJob(jobCreateParam); err != nil {
		log.Println(err)
		return err
	}
	return nil
}

func CreateMobileJob(createParam MobileJobCreateParam)  error {
	// parse script
	scriptTemplate, err := ioutil.ReadFile(createParam.JobScriptTemplateFile)
	if err != nil {
		log.Println(err)
		return err
	}
	tmpl, err := template.New("scriptTemplate").Parse(string(scriptTemplate))
	if err != nil {
		log.Println(err)
		return err
	}
	var scriptContent bytes.Buffer
	err = tmpl.Execute(&scriptContent, createParam)
	if err != nil {
		log.Println(err)
		return err
	}
	// parse the customer portal job template
	configTemplate, err := ioutil.ReadFile(createParam.JobConfigTemplateFile)
	if err != nil {
		log.Println(err)
		return err
	}
	tmpl, err = template.New("configTemplate").Parse(string(configTemplate))
	if err != nil {
		log.Println(err)
		return err
	}
	jobParam := JobParam{
		Script: scriptContent.String(),
	}
	var jobConfig bytes.Buffer
	err = tmpl.Execute(&jobConfig, jobParam)
	if err != nil {
		log.Println(err)
		return err
	}
	// create job under view
	jobCreateParam := JobCreateParam{
		EnvName: strings.ToUpper(createParam.EnvName),
		JobName: createParam.JobName,
		Config:  &jobConfig,
	}
	if err = CreateViewJob(jobCreateParam); err != nil {
		log.Println(err)
		return err
	}
	return nil
}

func CreateDBJob(createParam DBJobCreateParam)  error {
	// parse script
	scriptTemplate, err := ioutil.ReadFile(createParam.JobScriptTemplateFile)
	if err != nil {
		log.Println(err)
		return err
	}
	tmpl, err := template.New("scriptTemplate").Parse(string(scriptTemplate))
	if err != nil {
		log.Println(err)
		return err
	}
	var scriptContent bytes.Buffer
	err = tmpl.Execute(&scriptContent, createParam)
	if err != nil {
		log.Println(err)
		return err
	}
	// escape " ' < > &
	var escapedScript bytes.Buffer
	err = xml.EscapeText(&escapedScript, scriptContent.Bytes())
	if err != nil {
		log.Println(err)
		return err
	}
	// parse the customer portal job template
	configTemplate, err := ioutil.ReadFile(createParam.JobConfigTemplateFile)
	if err != nil {
		log.Println(err)
		return err
	}
	tmpl, err = template.New("configTemplate").Parse(string(configTemplate))
	if err != nil {
		log.Println(err)
		return err
	}
	jobParam := JobParam{
		Script: escapedScript.String(),
	}
	var jobConfig bytes.Buffer
	err = tmpl.Execute(&jobConfig, jobParam)
	if err != nil {
		log.Println(err)
		return err
	}
	// create job under view
	jobCreateParam := JobCreateParam{
		EnvName: strings.ToUpper(createParam.EnvName),
		JobName: createParam.JobName,
		Config:  &jobConfig,
	}
	if err = CreateViewJob(jobCreateParam); err != nil {
		log.Println(err)
		return err
	}
	return nil
}

func CreateApplicationRestartJob(createParam ApplicationRestartJobCreateParam)  error {
	// parse script
	scriptTemplate, err := ioutil.ReadFile(createParam.JobScriptTemplateFile)
	if err != nil {
		log.Println(err)
		return err
	}
	tmpl, err := template.New("scriptTemplate").Parse(string(scriptTemplate))
	if err != nil {
		log.Println(err)
		return err
	}
	var scriptContent bytes.Buffer
	err = tmpl.Execute(&scriptContent, createParam)
	if err != nil {
		log.Println(err)
		return err
	}
	// escape " ' < > &
	var escapedScript bytes.Buffer
	err = xml.EscapeText(&escapedScript, scriptContent.Bytes())
	if err != nil {
		log.Println(err)
		return err
	}
	// parse the customer portal job template
	configTemplate, err := ioutil.ReadFile(createParam.JobConfigTemplateFile)
	if err != nil {
		log.Println(err)
		return err
	}
	tmpl, err = template.New("configTemplate").Parse(string(configTemplate))
	if err != nil {
		log.Println(err)
		return err
	}
	jobParam := JobParam{
		Script: escapedScript.String(),
	}
	var jobConfig bytes.Buffer
	err = tmpl.Execute(&jobConfig, jobParam)
	if err != nil {
		log.Println(err)
		return err
	}
	// create job under view
	jobCreateParam := JobCreateParam{
		EnvName: strings.ToUpper(createParam.EnvName),
		JobName: createParam.JobName,
		Config:  &jobConfig,
	}
	if err = CreateViewJob(jobCreateParam); err != nil {
		log.Println(err)
		return err
	}
	return nil
}
